package com.yzy.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.yzy.domain.dto.system.RolePermissionDTO;
import com.yzy.domain.entity.system.PermissionEnum;
import com.yzy.domain.entity.system.Role;
import com.yzy.domain.entity.system.RoleTypeEnum;
import com.yzy.exception.VisionException;
import com.yzy.mapper.system.RolePermissionMapper;
import com.yzy.service.AccountService;
import com.yzy.service.RolePermissionService;
import com.yzy.service.RoleService;
import com.yzy.domain.vo.system.AccountVo;
import com.yzy.domain.entity.system.RolePermission;
import org.springframework.http.HttpStatus;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.HashSet;
import java.util.List;

@Service
public class RolePermissionServiceImpl implements RolePermissionService {

    @Resource
    private RolePermissionMapper rolePermissionMapper;

    @Resource
    private RoleService roleService;

    @Resource
    private AccountService accountService;

    @Override
    public void checkPermission(PermissionEnum[] permissions, String accountId, String message) {
        if (!checkArray(permissions, accountId)) {
            throw new VisionException(HttpStatus.FORBIDDEN, message);
        }
    }

    @Override
    public void checkPermission(PermissionEnum[] permissions, String accountId) {
        if (!checkArray(permissions, accountId)) {
            throw new VisionException(HttpStatus.FORBIDDEN, "对不起, 您无权访问该页面!");
        }
    }

    @Override
    public void checkPermission(PermissionEnum permission, String accountId) {
        if (!check(permission, accountId)) {
            throw new VisionException(HttpStatus.FORBIDDEN, "对不起, 您无权访问该页面!");
        }
    }

    @Override
    public void checkPermission(PermissionEnum permission, String accountId, String message) {
        if (!check(permission, accountId)) {
            throw new VisionException(HttpStatus.FORBIDDEN, message);
        }
    }

    @Override
    public boolean checkAdmin(String accountId) {
        AccountVo accountVo = accountService.findVoById(accountId);
        return RoleTypeEnum.ADMIN == accountVo.getRoleType();
    }

    @Override
    public RolePermission findByRoleIdAndPermission(PermissionEnum permission, String roleId) {
        LambdaQueryWrapper<RolePermission> baseWrapper = new LambdaQueryWrapper<>();
        baseWrapper.eq(RolePermission::getRoleId, roleId);
        baseWrapper.eq(RolePermission::getPermission, permission);
        return rolePermissionMapper.selectOne(baseWrapper);
    }

    @Override
    public List<RolePermission> getPermissionByRoleId(String roleId) {
        LambdaQueryWrapper<RolePermission> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(RolePermission::getRoleId, roleId);
        return rolePermissionMapper.selectList(wrapper);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void saveOrUpdatePermission(RolePermissionDTO rolePermissionDTO, String accountId) {
        Role role = roleService.findByRoleId(rolePermissionDTO.getRoleId());
        if (RoleTypeEnum.ADMIN == role.getType()) {
            throw new VisionException(HttpStatus.FORBIDDEN, "超级管理员角色不允许修改权限！！！");
        }
        LambdaUpdateWrapper<RolePermission> wrapper = new LambdaUpdateWrapper<>();
        wrapper.eq(RolePermission::getRoleId, rolePermissionDTO.getRoleId());
        rolePermissionMapper.delete(wrapper);

        rolePermissionMapper.batchInsert(new HashSet<>(rolePermissionDTO.getList()), rolePermissionDTO.getRoleId());
    }

    private boolean checkArray(PermissionEnum[] permissions, String accountId) {
        Role role = roleService.findByAccountId(accountId);
        if (RoleTypeEnum.ADMIN.equals(role.getType())) {
            return true;
        }

        for (PermissionEnum permission : permissions) {
            RolePermission rolePermission = findByRoleIdAndPermission(permission, role.getId());
            if (null != rolePermission) {
                return true;
            }
        }
        return false;
    }

    private boolean check(PermissionEnum permission, String accountId) {
        Role role = roleService.findByAccountId(accountId);
        if (RoleTypeEnum.ADMIN.equals(role.getType())) {
            return true;
        }

        return findByRoleIdAndPermission(permission, role.getId()) != null;
    }


}
